'use strict';

let {Sequelize,DataTypes} =require('sequelize');
let {database,username,password,host,dialect}=require('./config');

// 实例化一个Sequelize的实例
let sequelize=new Sequelize(database,username,password,{
    host:host,
    dialect:dialect
});

// 创建一个函数，包装模型的统一定义
function defineModel(name,attrs){
    let prop={};

    // 模型的id
    prop.id={
        type:DataTypes.BIGINT,
        primaryKey:true,
        autoIncrement:true
    };

    // 将外部定义的模型的属性全部加载进来 
    for(let key in attrs){
        let value=attrs[key];
        prop[key]=value;
    }

    // 创建时间
    prop.createdAt={
        type:DataTypes.BIGINT,
        allowNull:false
    }
    // 更新时间
    prop.updatedAt={
        type:DataTypes.BIGINT,
        allowNull:false
    }
    // 版本
    prop.version={
        type:DataTypes.BIGINT,
        allowNull:false
    }
    // 备注
    prop.remarks={
        type:DataTypes.BIGINT,
        allowNull:true
    }

    // 真正利用Sequelize的实例定义一个模型的方式
    let obj=sequelize.define(name,prop,{
        tableName:name,     // 指定表名称为模型名称（即模型名称和表名称是一致的）
        timestamps:false,   // 不自动创建createdAt、updatedAt这两个字段（或者属性）
        // 勾子对象
        hooks:{
            // 生命周期勾子,意思是在，对将要插入或更新到数据库的数据进行验证之前，执行的方法（这里就是在验证数据之前，给createdAt、updatedAt添加指定的值）
            beforeValidate:function(obj){
                // 获取时间戳
                let now=Date.now();

                // 如果数据是将要插入的数据
                if(obj.isNewRecord){
                    obj.createdAt=now;
                    obj.updatedAt=now;
                    obj.version=0;
                }else{
                    obj.updatedAt=now;
                    obj.version+=1;
                }
            }
        }
    });

    return obj;
}

// 创建一个对象，包含一个实例、一个定义模型的函数、一个模型的数据类型
let obj={
    sequelize,
    defineModel,
    DataTypes
};

module.exports=obj;
